package com.learning.platform.service;

import com.learning.platform.enums.QueryIntent;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.regex.Pattern;

/**
 * AI意图识别服务
 * 分析用户查询内容，识别查询意图
 */
@Service
public class IntentRecognitionService {
    
    // 编程关键词集合
    private static final Set<String> PROGRAMMING_KEYWORDS = Set.of(
        "代码", "编程", "程序", "算法", "数据结构", "函数", "方法", "类", "对象",
        "变量", "循环", "条件", "数组", "列表", "字典", "哈希", "树", "图",
        "java", "python", "javascript", "c++", "c#", "go", "rust", "php",
        "html", "css", "sql", "mysql", "mongodb", "redis", "spring", "vue",
        "react", "angular", "nodejs", "express", "django", "flask", "api",
        "rest", "json", "xml", "http", "tcp", "udp", "git", "docker"
    );
    
    // 代码调试关键词
    private static final Set<String> DEBUG_KEYWORDS = Set.of(
        "错误", "报错", "异常", "bug", "调试", "debug", "修复", "解决",
        "不工作", "不运行", "崩溃", "卡死", "性能", "优化", "慢",
        "nullpointerexception", "stackoverflow", "outofmemory",
        "syntaxerror", "typeerror", "referenceerror"
    );
    
    // 代码审查关键词
    private static final Set<String> REVIEW_KEYWORDS = Set.of(
        "代码审查", "code review", "最佳实践", "代码质量", "重构", "优化",
        "规范", "标准", "可读性", "维护性", "性能优化", "设计模式",
        "clean code", "代码风格", "命名规范"
    );
    
    // 概念解释关键词
    private static final Set<String> CONCEPT_KEYWORDS = Set.of(
        "什么是", "如何理解", "解释", "原理", "概念", "定义", "区别",
        "比较", "优缺点", "特点", "用途", "应用场景", "工作原理"
    );
    
    // 项目帮助关键词
    private static final Set<String> PROJECT_KEYWORDS = Set.of(
        "项目", "系统", "架构", "设计", "开发", "实现", "搭建",
        "技术选型", "框架选择", "数据库设计", "系统设计", "微服务",
        "分布式", "高并发", "高可用", "负载均衡", "缓存"
    );
    
    // 学习相关关键词
    private static final Set<String> LEARNING_KEYWORDS = Set.of(
        "学习", "教程", "课程", "练习", "作业", "考试", "复习",
        "计划", "方法", "技巧", "建议", "推荐", "资源", "书籍",
        "视频", "文档", "入门", "进阶", "提升", "掌握"
    );
    
    // 代码模式正则表达式
    private static final List<Pattern> CODE_PATTERNS = List.of(
        Pattern.compile("```[\\s\\S]*?```"),  // 代码块
        Pattern.compile("`[^`]+`"),           // 行内代码
        Pattern.compile("\\b\\w+\\(.*?\\)"),  // 函数调用
        Pattern.compile("\\b\\w+\\.\\w+"),    // 方法调用
        Pattern.compile("\\b(class|function|def|var|let|const)\\b", Pattern.CASE_INSENSITIVE)
    );
    
    /**
     * 识别查询意图
     */
    public QueryIntent identifyIntent(String query) {
        if (query == null || query.trim().isEmpty()) {
            return QueryIntent.GENERAL;
        }
        
        String lowerQuery = query.toLowerCase();
        
        // 检查是否包含代码模式
        boolean hasCodePattern = CODE_PATTERNS.stream()
            .anyMatch(pattern -> pattern.matcher(query).find());
        
        // 计算各类关键词的匹配度
        int debugScore = calculateKeywordScore(lowerQuery, DEBUG_KEYWORDS);
        int reviewScore = calculateKeywordScore(lowerQuery, REVIEW_KEYWORDS);
        int conceptScore = calculateKeywordScore(lowerQuery, CONCEPT_KEYWORDS);
        int projectScore = calculateKeywordScore(lowerQuery, PROJECT_KEYWORDS);
        int programmingScore = calculateKeywordScore(lowerQuery, PROGRAMMING_KEYWORDS);
        int learningScore = calculateKeywordScore(lowerQuery, LEARNING_KEYWORDS);
        
        // 如果包含代码模式，增加编程相关分数
        if (hasCodePattern) {
            programmingScore += 5;
            debugScore += 3;
            reviewScore += 3;
        }
        
        // 根据分数确定意图
        Map<QueryIntent, Integer> scores = new HashMap<>();
        scores.put(QueryIntent.CODE_DEBUG, debugScore);
        scores.put(QueryIntent.CODE_REVIEW, reviewScore);
        scores.put(QueryIntent.CONCEPT_EXPLANATION, conceptScore);
        scores.put(QueryIntent.PROJECT_HELP, projectScore);
        scores.put(QueryIntent.PROGRAMMING, programmingScore);
        scores.put(QueryIntent.LEARNING, learningScore);
        
        // 找到最高分的意图
        return scores.entrySet().stream()
            .filter(entry -> entry.getValue() > 0)
            .max(Map.Entry.comparingByValue())
            .map(Map.Entry::getKey)
            .orElse(QueryIntent.GENERAL);
    }
    
    /**
     * 计算关键词匹配分数
     */
    private int calculateKeywordScore(String query, Set<String> keywords) {
        return (int) keywords.stream()
            .mapToLong(keyword -> countOccurrences(query, keyword))
            .sum();
    }
    
    /**
     * 计算关键词出现次数
     */
    private long countOccurrences(String text, String keyword) {
        int count = 0;
        int index = 0;
        while ((index = text.indexOf(keyword, index)) != -1) {
            count++;
            index += keyword.length();
        }
        return count;
    }
    
    /**
     * 获取意图的详细信息
     */
    public IntentAnalysisResult analyzeIntent(String query) {
        QueryIntent intent = identifyIntent(query);
        
        return IntentAnalysisResult.builder()
            .intent(intent)
            .confidence(calculateConfidence(query, intent))
            .keywords(extractMatchedKeywords(query, intent))
            .hasCodePattern(hasCodePattern(query))
            .complexity(calculateQueryComplexity(query))
            .build();
    }
    
    /**
     * 计算意图识别的置信度
     */
    private double calculateConfidence(String query, QueryIntent intent) {
        String lowerQuery = query.toLowerCase();
        Set<String> relevantKeywords = getRelevantKeywords(intent);
        
        int matchedKeywords = calculateKeywordScore(lowerQuery, relevantKeywords);
        int totalWords = query.split("\\s+").length;
        
        double keywordRatio = (double) matchedKeywords / Math.max(totalWords, 1);
        double baseConfidence = Math.min(keywordRatio * 2, 1.0);
        
        // 如果包含代码模式且是编程相关意图，提高置信度
        if (hasCodePattern(query) && intent.isProgrammingRelated()) {
            baseConfidence = Math.min(baseConfidence + 0.3, 1.0);
        }
        
        return baseConfidence;
    }
    
    /**
     * 提取匹配的关键词
     */
    private List<String> extractMatchedKeywords(String query, QueryIntent intent) {
        String lowerQuery = query.toLowerCase();
        Set<String> relevantKeywords = getRelevantKeywords(intent);
        
        return relevantKeywords.stream()
            .filter(keyword -> lowerQuery.contains(keyword))
            .sorted()
            .toList();
    }
    
    /**
     * 检查是否包含代码模式
     */
    private boolean hasCodePattern(String query) {
        return CODE_PATTERNS.stream()
            .anyMatch(pattern -> pattern.matcher(query).find());
    }
    
    /**
     * 计算查询复杂度
     */
    private String calculateQueryComplexity(String query) {
        int wordCount = query.split("\\s+").length;
        
        if (wordCount <= 5) return "简单";
        if (wordCount <= 15) return "中等";
        return "复杂";
    }
    
    /**
     * 获取相关关键词集合
     */
    private Set<String> getRelevantKeywords(QueryIntent intent) {
        return switch (intent) {
            case CODE_DEBUG -> DEBUG_KEYWORDS;
            case CODE_REVIEW -> REVIEW_KEYWORDS;
            case CONCEPT_EXPLANATION -> CONCEPT_KEYWORDS;
            case PROJECT_HELP -> PROJECT_KEYWORDS;
            case PROGRAMMING -> PROGRAMMING_KEYWORDS;
            case LEARNING -> LEARNING_KEYWORDS;
            default -> Set.of();
        };
    }
    
    /**
     * 意图分析结果
     */
    public static class IntentAnalysisResult {
        private QueryIntent intent;
        private double confidence;
        private List<String> keywords;
        private boolean hasCodePattern;
        private String complexity;
        
        public static Builder builder() {
            return new Builder();
        }
        
        // Getters
        public QueryIntent getIntent() { return intent; }
        public double getConfidence() { return confidence; }
        public List<String> getKeywords() { return keywords; }
        public boolean isHasCodePattern() { return hasCodePattern; }
        public String getComplexity() { return complexity; }
        
        public static class Builder {
            private IntentAnalysisResult result = new IntentAnalysisResult();
            
            public Builder intent(QueryIntent intent) {
                result.intent = intent;
                return this;
            }
            
            public Builder confidence(double confidence) {
                result.confidence = confidence;
                return this;
            }
            
            public Builder keywords(List<String> keywords) {
                result.keywords = keywords;
                return this;
            }
            
            public Builder hasCodePattern(boolean hasCodePattern) {
                result.hasCodePattern = hasCodePattern;
                return this;
            }
            
            public Builder complexity(String complexity) {
                result.complexity = complexity;
                return this;
            }
            
            public IntentAnalysisResult build() {
                return result;
            }
        }
    }
}
